Skip to content

infra(cpb): add database, env vars, and setup scripts for Connecting People Bot#120

Merged
SashkoMarchuk merged 7 commits intomainfrom
feature/cpb-infrastructure
Apr 5, 2026
Merged

infra(cpb): add database, env vars, and setup scripts for Connecting People Bot#120
SashkoMarchuk merged 7 commits intomainfrom
feature/cpb-infrastructure

Conversation

@SashkoMarchuk
Copy link
Copy Markdown
Collaborator

@SashkoMarchuk SashkoMarchuk commented Apr 2, 2026

Summary

  • Add CPB (Connecting People Bot) PostgreSQL database infrastructure: dedicated cpb_bot database, cpb_app user, and all required environment variables
  • Add scripts/cpb-setup-db.sh — idempotent production database setup script with SQL injection protection and error handling
  • Append CPB user/database creation to scripts/init-db.sh for dev environment auto-initialization

All changes are additive — no existing n8n or Temporal functionality is modified.

Files Changed

File Change
.env.example CPB variables for dev (with defaults) and prod (with placeholders) sections
docker-compose.yml CPB env vars for postgresql service (3 vars) + n8n service (14 vars)
docker-compose.prod.yml CPB env vars for n8n service with :?required / :-default syntax
scripts/init-db.sh Append CPB user/database creation block (dev auto-init)
scripts/cpb-setup-db.sh New file — idempotent production database setup

Security Hardening

The production setup script (cpb-setup-db.sh) includes:

  • SQL injection prevention: validate_pg_identifier() function validates username/database name against ^[a-zA-Z_][a-zA-Z0-9_]*$ with 63-char PostgreSQL limit
  • Error detection: -v ON_ERROR_STOP=1 ensures psql exits on SQL errors (not silently ignored)
  • Pipeline safety: set -eo pipefail catches both command and pipeline failures
  • Password escaping: Single quotes escaped for SQL string literal safety

Setup Guide for DevOps

Development (fresh setup)

# 1. Copy env vars (CPB defaults are already included)
cp .env.example .env
# Edit .env — set CPB_SLACK_BOT_TOKEN to existing SLACK_TOKEN value for dev testing

# 2. Start services (fresh volume required for init-db.sh to run)
docker compose down -v
docker compose up -d

# 3. Verify CPB database exists
docker compose exec postgresql psql -U cpb_app -d cpb_bot -c "SELECT 1"

# 4. Verify CPB env vars are visible to n8n
docker compose exec n8n env | grep CPB_

Development (existing volume)

If you already have a running PostgreSQL volume, init-db.sh won't re-run. Create the CPB database manually:

docker compose exec postgresql psql -U postgres <<-EOSQL
    CREATE USER cpb_app WITH ENCRYPTED PASSWORD 'cpb_password';
    CREATE DATABASE cpb_bot OWNER cpb_app;
    GRANT ALL PRIVILEGES ON DATABASE cpb_bot TO cpb_app;
EOSQL

# Restart n8n to pick up new env vars
docker compose restart n8n
docker compose exec n8n env | grep CPB_

Production

# 1. Generate a secure password
openssl rand -base64 32

# 2. Run the idempotent setup script
POSTGRES_PASSWORD_CPB="<generated-password>" \
CPB_POSTGRES_HOST="<prod-postgresql-host>" \
./scripts/cpb-setup-db.sh

# 3. Update production .env with real values:
#    - POSTGRES_PASSWORD_CPB (the generated password)
#    - CPB_POSTGRES_HOST (already set via POSTGRES_HOST)
#    - CPB_SLACK_BOT_TOKEN (from Al — CPB-specific xoxb- token)
#    - CPB_CHANNEL_ID, CPB_REPORT_CHANNEL_ID (from Olivia/Al)
#    - CPB_ADMIN_SLACK_ID, CPB_DEV_SLACK_ID (Slack user IDs)

# 4. Deploy
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# 5. Verify
docker compose exec n8n env | grep CPB_

Environment Variables Reference

Variable Dev Default Prod Description
POSTGRES_DB_CPB cpb_bot cpb_bot Database name
POSTGRES_USER_CPB cpb_app cpb_app Database user
POSTGRES_PASSWORD_CPB cpb_password generate Database password
CPB_SLACK_BOT_TOKEN xoxb-placeholder from Al Slack bot token
CPB_CHANNEL_ID CXXXXXXXXX from Olivia CPB community channel
CPB_REPORT_CHANNEL_ID CXXXXXXXXX from Al Admin report channel
CPB_ADMIN_SLACK_ID UXXXXXXXXX from Olivia Admin Slack user ID
CPB_DEV_SLACK_ID UXXXXXXXXX from Sashko Developer Slack user ID
CPB_PAIRING_LAMBDA 0.0578 0.0578 Pairing decay rate
CPB_PAIRING_ALPHA 0.3 0.3 Repeat penalty
CPB_PAIRING_TRIALS 50 50 Matching trials
CPB_PAIRING_MIN_WEIGHT 0.01 0.01 Minimum weight floor

Rollback

All changes are additive. To rollback:

# Dev: remove volumes and revert
docker compose down -v
git revert <this-commit>
docker compose up -d

# Prod: drop CPB database/user
psql -h <prod-host> -U postgres -c "DROP DATABASE IF EXISTS cpb_bot; DROP ROLE IF EXISTS cpb_app;"

Test Plan

  • docker compose config --quiet passes (dev config valid)
  • docker compose -f docker-compose.yml -f docker-compose.prod.yml config --quiet validates (prod config — will error on missing required vars, expected)
  • bash -n scripts/cpb-setup-db.sh passes (no syntax errors)
  • grep -c "CPB" scripts/init-db.sh returns 3 (user, database, grant)
  • test -x scripts/cpb-setup-db.sh confirms executable
  • Fresh docker compose up -d (after down -v) creates cpb_bot database
  • docker compose exec postgresql psql -U cpb_app -d cpb_bot -c "SELECT 1" returns 1
  • docker compose exec n8n env | grep CPB_ lists all 14 CPB variables

Summary by CodeRabbit

  • New Features

    • Added a Connecting People Bot: Slack-based pairing with persistent storage and configurable pairing parameters (lambda, alpha, trials, min weight).
  • Chores

    • Added Development/Production environment configuration and automated DB provisioning/init support to simplify setup and deployment.

SashkoMarchuk and others added 2 commits April 2, 2026 15:03
- .env.example: CPB variables for dev and prod sections
- .env: CPB dev defaults (using Reporter Bot token for testing)
- docker-compose.yml: CPB env vars for postgresql + n8n services
- docker-compose.prod.yml: CPB env vars for n8n (prod overrides)
- scripts/init-db.sh: append CPB user/database creation block
- scripts/cpb-setup-db.sh: new idempotent production DB setup script

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…lures

- Add identifier validation for username/database name (regex + 63-char limit)
- Add -v ON_ERROR_STOP=1 to psql invocation to catch SQL errors
- Add pipefail to catch pipeline failures
- Fix misleading comment on password escaping

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@SashkoMarchuk SashkoMarchuk requested a review from killev as a code owner April 2, 2026 15:19
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 2, 2026

CodeRabbit CodeRabbit

🤖 CodeRabbit AI Review Available

To request a code review from CodeRabbit AI, add [coderabbit-ai-review] to your PR title.

CodeRabbit will analyze your code and provide feedback on:

  • Logic and correctness
  • Security issues
  • Performance optimizations
  • Code quality and best practices
  • Error handling
  • Maintainability

Note: Reviews are only performed when [coderabbit-ai-review] is present in the PR title.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 2, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: b76b0271-bae4-4bb4-9135-c9333b72e931

📥 Commits

Reviewing files that changed from the base of the PR and between 4c3dded and d2ed4f8.

📒 Files selected for processing (3)
  • .env.example
  • docker-compose.prod.yml
  • scripts/init-db.sh
🚧 Files skipped from review as they are similar to previous changes (2)
  • scripts/init-db.sh
  • docker-compose.prod.yml

📝 Walkthrough

Walkthrough

Adds CPB (Connecting People Bot) configuration: new environment variables in .env.example, Docker Compose entries for n8n and Postgres, a provisioning script scripts/cpb-setup-db.sh, and updates to scripts/init-db.sh to create and grant a CPB Postgres role/database.

Changes

Cohort / File(s) Summary
Env examples & compose
.env.example, docker-compose.yml, docker-compose.prod.yml
Added CPB env vars: Postgres provisioning keys (POSTGRES_DB_CPB, POSTGRES_USER_CPB, POSTGRES_PASSWORD_CPB), runtime DB connection (CPB_POSTGRES_*), Slack tokens/IDs (CPB_SLACK_BOT_TOKEN, CPB_CHANNEL_ID, CPB_REPORT_CHANNEL_ID, CPB_ADMIN_SLACK_ID, CPB_DEV_SLACK_ID), and pairing tuning params (CPB_PAIRING_LAMBDA, CPB_PAIRING_ALPHA, CPB_PAIRING_TRIALS, CPB_PAIRING_MIN_WEIGHT) with defaults/fallbacks.
DB provisioning scripts
scripts/cpb-setup-db.sh, scripts/init-db.sh
Added scripts/cpb-setup-db.sh to idempotently create CPB role/database with identifier validation and SQL-escaped passwords; updated scripts/init-db.sh to validate identifiers and create/grant the CPB role/database using escaped passwords.

Sequence Diagram(s)

sequenceDiagram
  participant Operator as Operator
  participant Provision as cpb-setup-db.sh
  participant InitScript as init-db.sh
  participant Postgres as PostgreSQL
  participant n8n as n8n Service
  participant Slack as Slack API

  Operator->>Provision: run provisioning (CPB_POSTGRES_HOST, POSTGRES_PASSWORD_CPB, ...)
  Provision->>Postgres: CREATE ROLE IF NOT EXISTS (validated idents, escaped pwd)
  Provision->>Postgres: CREATE DATABASE IF NOT EXISTS (owner CPB role)
  Provision->>Postgres: GRANT ALL PRIVILEGES ON DATABASE TO ROLE
  Operator->>InitScript: run init (creates CPB role/db if part of init)
  Operator->>n8n: start service with CPB env vars
  n8n->>Postgres: connect to CPB DB using CPB_POSTGRES_*
  n8n->>Slack: use CPB_SLACK_BOT_TOKEN to post/communicate
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • DenisChistyakov
  • killev

Poem

🐰 I hopped in with vars and a script so spry,
Creating roles and DBs beneath the sky.
Env keys lined up, containers hum along,
CPB pairs and chats — a rabbit's little song,
Deploys complete, I nibble and I sigh.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding database, environment variables, and setup scripts for the Connecting People Bot infrastructure.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/cpb-infrastructure

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.env.example:
- Around line 117-133: This file contains duplicate CPB environment variables
(e.g., POSTGRES_DB_CPB, POSTGRES_USER_CPB, CPB_POSTGRES_HOST, CPB_POSTGRES_DB,
CPB_POSTGRES_USER, CPB_POSTGRES_PASSWORD, CPB_SLACK_BOT_TOKEN, CPB_CHANNEL_ID,
CPB_REPORT_CHANNEL_ID, CPB_ADMIN_SLACK_ID, CPB_DEV_SLACK_ID, CPB_PAIRING_* )
which will override the earlier development entries; remove the duplicate
production block or split into separate templates (e.g., .env.example.dev and
.env.example.prod) so each variable name appears only once in a given template
and placeholders like CPB_CHANNEL_ID/CPB_REPORT_CHANNEL_ID remain unambiguous
for developers to fill.

In `@docker-compose.prod.yml`:
- Around line 45-48: The compose file currently supplies placeholder defaults
for Slack IDs (CPB_CHANNEL_ID, CPB_REPORT_CHANNEL_ID, CPB_ADMIN_SLACK_ID,
CPB_DEV_SLACK_ID) which permits startup with invalid values; change these to be
required by removing the ":-FILL_BEFORE_LAUNCH" defaults and instead use a
strict expansion form (e.g., ${CPB_CHANNEL_ID:?CPB_CHANNEL_ID is required}) for
each variable so the process fails fast at launch if any Slack ID is missing.

In `@scripts/cpb-setup-db.sh`:
- Line 52: The psql call currently hardcodes the admin user with "-U postgres",
which breaks environments that use a different superuser; update the psql
invocation (the line containing "psql -v ON_ERROR_STOP=1 -h \"$PGHOST\" -p
\"$PGPORT\" -U postgres <<-EOSQL") to honor an environment-configurable
superuser variable (e.g. PGUSER, PGSUPERUSER or a new ADMIN_DB_USER) and default
sensibly if unset, then use that variable in place of the hardcoded "-U
postgres" so external PostgreSQL setups can supply their admin username.

In `@scripts/init-db.sh`:
- Around line 17-19: The CREATE USER SQL inserts the raw $POSTGRES_PASSWORD_CPB
into a single-quoted SQL literal which breaks if the password contains a single
quote and can allow injection; before building the SQL statements (the CREATE
USER "$POSTGRES_USER_CPB" WITH ENCRYPTED PASSWORD ... line), sanitize/escape the
password by doubling any single quotes (e.g.
ESCAPED_PASSWORD=${POSTGRES_PASSWORD_CPB//\'/\'\'}), then use that escaped
variable in the SQL string instead of the raw $POSTGRES_PASSWORD_CPB; ensure the
same escaped value is used wherever the password literal is injected.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: b2dd31be-8d7e-4edc-b645-fd2601c3f0f5

📥 Commits

Reviewing files that changed from the base of the PR and between 90f3fd2 and 8c673c3.

📒 Files selected for processing (5)
  • .env.example
  • docker-compose.prod.yml
  • docker-compose.yml
  • scripts/cpb-setup-db.sh
  • scripts/init-db.sh

- Remove duplicate CPB env vars from production section in .env.example
- Make Slack IDs required (:?) in docker-compose.prod.yml instead of defaulting to placeholders
- Make PostgreSQL admin user configurable via CPB_POSTGRES_ADMIN_USER in cpb-setup-db.sh
- Fix password escaping in init-db.sh and cpb-setup-db.sh (use '' not \'\')

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 2, 2026

🔍 Vulnerabilities of temporal-test:latest

📦 Image Reference temporal-test:latest
digestsha256:17e54ff5e9a181d1bdbf7334ce9637f9c3934d54a65427ae36a5743f46487f15
vulnerabilitiescritical: 7 high: 36 medium: 0 low: 0
platformlinux/amd64
size218 MB
packages358
📦 Base Image alpine:3
also known as
  • 3.21
  • 3.21.3
  • latest
digestsha256:1c4eef651f65e2f7daee7ee785882ac164b02b78fb74503052a26dc061c90474
vulnerabilitiescritical: 0 high: 5 medium: 9 low: 3
critical: 2 high: 7 medium: 0 low: 0 stdlib 1.23.2 (golang)

pkg:golang/stdlib@1.23.2

critical : CVE--2025--68121

Affected range<1.24.13
Fixed version1.24.13
EPSS Score0.017%
EPSS Percentile4th percentile
Description

During session resumption in crypto/tls, if the underlying Config has its ClientCAs or RootCAs fields mutated between the initial handshake and the resumed handshake, the resumed handshake may succeed when it should have failed. This may happen when a user calls Config.Clone and mutates the returned Config, or uses Config.GetConfigForClient. This can cause a client to resume a session with a server that it would not have resumed with during the initial handshake, or cause a server to resume a session with a client that it would not have resumed with during the initial handshake.

critical : CVE--2025--22871

Affected range<1.23.8
Fixed version1.23.8
EPSS Score0.127%
EPSS Percentile32nd percentile
Description

The net/http package improperly accepts a bare LF as a line terminator in chunked data chunk-size lines. This can permit request smuggling if a net/http server is used in conjunction with a server that incorrectly accepts a bare LF as part of a chunk-ext.

high : CVE--2026--25679

Affected range<1.25.8
Fixed version1.25.8
EPSS Score0.031%
EPSS Percentile9th percentile
Description

url.Parse insufficiently validated the host/authority component and accepted some invalid URLs.

high : CVE--2025--61729

Affected range<1.24.11
Fixed version1.24.11
EPSS Score0.023%
EPSS Percentile6th percentile
Description

Within HostnameError.Error(), when constructing an error string, there is no limit to the number of hosts that will be printed out. Furthermore, the error string is constructed by repeated string concatenation, leading to quadratic runtime. Therefore, a certificate provided by a malicious actor can result in excessive resource consumption.

high : CVE--2025--61726

Affected range<1.24.12
Fixed version1.24.12
EPSS Score0.032%
EPSS Percentile9th percentile
Description

The net/url package does not set a limit on the number of query parameters in a query.

While the maximum size of query parameters in URLs is generally limited by the maximum request header size, the net/http.Request.ParseForm method can parse large URL-encoded forms. Parsing a large form containing many unique query parameters can cause excessive memory consumption.

high : CVE--2025--61725

Affected range<1.24.8
Fixed version1.24.8
EPSS Score0.028%
EPSS Percentile8th percentile
Description

The ParseAddress function constructs domain-literal address components through repeated string concatenation. When parsing large domain-literal components, this can cause excessive CPU consumption.

high : CVE--2025--61723

Affected range<1.24.8
Fixed version1.24.8
EPSS Score0.027%
EPSS Percentile8th percentile
Description

The processing time for parsing some invalid inputs scales non-linearly with respect to the size of the input.

This affects programs which parse untrusted PEM inputs.

high : CVE--2025--58188

Affected range<1.24.8
Fixed version1.24.8
EPSS Score0.006%
EPSS Percentile0th percentile
Description

Validating certificate chains which contain DSA public keys can cause programs to panic, due to a interface cast that assumes they implement the Equal method.

This affects programs which validate arbitrary certificate chains.

high : CVE--2025--58187

Affected range<1.24.9
Fixed version1.24.9
EPSS Score0.013%
EPSS Percentile2nd percentile
Description

Due to the design of the name constraint checking algorithm, the processing time of some inputs scale non-linearly with respect to the size of the certificate.

This affects programs which validate arbitrary certificate chains.

critical: 2 high: 7 medium: 0 low: 0 stdlib 1.23.6 (golang)

pkg:golang/stdlib@1.23.6

critical : CVE--2025--68121

Affected range<1.24.13
Fixed version1.24.13
EPSS Score0.017%
EPSS Percentile4th percentile
Description

During session resumption in crypto/tls, if the underlying Config has its ClientCAs or RootCAs fields mutated between the initial handshake and the resumed handshake, the resumed handshake may succeed when it should have failed. This may happen when a user calls Config.Clone and mutates the returned Config, or uses Config.GetConfigForClient. This can cause a client to resume a session with a server that it would not have resumed with during the initial handshake, or cause a server to resume a session with a client that it would not have resumed with during the initial handshake.

critical : CVE--2025--22871

Affected range<1.23.8
Fixed version1.23.8
EPSS Score0.127%
EPSS Percentile32nd percentile
Description

The net/http package improperly accepts a bare LF as a line terminator in chunked data chunk-size lines. This can permit request smuggling if a net/http server is used in conjunction with a server that incorrectly accepts a bare LF as part of a chunk-ext.

high : CVE--2026--25679

Affected range<1.25.8
Fixed version1.25.8
EPSS Score0.031%
EPSS Percentile9th percentile
Description

url.Parse insufficiently validated the host/authority component and accepted some invalid URLs.

high : CVE--2025--61729

Affected range<1.24.11
Fixed version1.24.11
EPSS Score0.023%
EPSS Percentile6th percentile
Description

Within HostnameError.Error(), when constructing an error string, there is no limit to the number of hosts that will be printed out. Furthermore, the error string is constructed by repeated string concatenation, leading to quadratic runtime. Therefore, a certificate provided by a malicious actor can result in excessive resource consumption.

high : CVE--2025--61726

Affected range<1.24.12
Fixed version1.24.12
EPSS Score0.032%
EPSS Percentile9th percentile
Description

The net/url package does not set a limit on the number of query parameters in a query.

While the maximum size of query parameters in URLs is generally limited by the maximum request header size, the net/http.Request.ParseForm method can parse large URL-encoded forms. Parsing a large form containing many unique query parameters can cause excessive memory consumption.

high : CVE--2025--61725

Affected range<1.24.8
Fixed version1.24.8
EPSS Score0.028%
EPSS Percentile8th percentile
Description

The ParseAddress function constructs domain-literal address components through repeated string concatenation. When parsing large domain-literal components, this can cause excessive CPU consumption.

high : CVE--2025--61723

Affected range<1.24.8
Fixed version1.24.8
EPSS Score0.027%
EPSS Percentile8th percentile
Description

The processing time for parsing some invalid inputs scales non-linearly with respect to the size of the input.

This affects programs which parse untrusted PEM inputs.

high : CVE--2025--58188

Affected range<1.24.8
Fixed version1.24.8
EPSS Score0.006%
EPSS Percentile0th percentile
Description

Validating certificate chains which contain DSA public keys can cause programs to panic, due to a interface cast that assumes they implement the Equal method.

This affects programs which validate arbitrary certificate chains.

high : CVE--2025--58187

Affected range<1.24.9
Fixed version1.24.9
EPSS Score0.013%
EPSS Percentile2nd percentile
Description

Due to the design of the name constraint checking algorithm, the processing time of some inputs scale non-linearly with respect to the size of the certificate.

This affects programs which validate arbitrary certificate chains.

critical: 1 high: 0 medium: 0 low: 0 google.golang.org/grpc 1.70.0 (golang)

pkg:golang/google.golang.org/grpc@1.70.0

critical 9.1: CVE--2026--33186 Improper Authorization

Affected range<1.79.3
Fixed version1.79.3
CVSS Score9.1
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
EPSS Score0.014%
EPSS Percentile3rd percentile
Description

Impact

What kind of vulnerability is it? Who is impacted?

It is an Authorization Bypass resulting from Improper Input Validation of the HTTP/2 :path pseudo-header.

The gRPC-Go server was too lenient in its routing logic, accepting requests where the :path omitted the mandatory leading slash (e.g., Service/Method instead of /Service/Method). While the server successfully routed these requests to the correct handler, authorization interceptors (including the official grpc/authz package) evaluated the raw, non-canonical path string. Consequently, "deny" rules defined using canonical paths (starting with /) failed to match the incoming request, allowing it to bypass the policy if a fallback "allow" rule was present.

Who is impacted?
This affects gRPC-Go servers that meet both of the following criteria:

  1. They use path-based authorization interceptors, such as the official RBAC implementation in google.golang.org/grpc/authz or custom interceptors relying on info.FullMethod or grpc.Method(ctx).
  2. Their security policy contains specific "deny" rules for canonical paths but allows other requests by default (a fallback "allow" rule).

The vulnerability is exploitable by an attacker who can send raw HTTP/2 frames with malformed :path headers directly to the gRPC server.

Patches

Has the problem been patched? What versions should users upgrade to?

Yes, the issue has been patched. The fix ensures that any request with a :path that does not start with a leading slash is immediately rejected with a codes.Unimplemented error, preventing it from reaching authorization interceptors or handlers with a non-canonical path string.

Users should upgrade to the following versions (or newer):

  • v1.79.3
  • The latest master branch.

It is recommended that all users employing path-based authorization (especially grpc/authz) upgrade as soon as the patch is available in a tagged release.

Workarounds

Is there a way for users to fix or remediate the vulnerability without upgrading?

While upgrading is the most secure and recommended path, users can mitigate the vulnerability using one of the following methods:

1. Use a Validating Interceptor (Recommended Mitigation)

Add an "outermost" interceptor to your server that validates the path before any other authorization logic runs:

func pathValidationInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
    if info.FullMethod == "" || info.FullMethod[0] != '/' {
        return nil, status.Errorf(codes.Unimplemented, "malformed method name")
    }   
    return handler(ctx, req)
}

// Ensure this is the FIRST interceptor in your chain
s := grpc.NewServer(
    grpc.ChainUnaryInterceptor(pathValidationInterceptor, authzInterceptor),
)

2. Infrastructure-Level Normalization

If your gRPC server is behind a reverse proxy or load balancer (such as Envoy, NGINX, or an L7 Cloud Load Balancer), ensure it is configured to enforce strict HTTP/2 compliance for pseudo-headers and reject or normalize requests where the :path header does not start with a leading slash.

3. Policy Hardening

Switch to a "default deny" posture in your authorization policies (explicitly listing all allowed paths and denying everything else) to reduce the risk of bypasses via malformed inputs.

critical: 1 high: 0 medium: 0 low: 0 google.golang.org/grpc 1.56.3 (golang)

pkg:golang/google.golang.org/grpc@1.56.3

critical 9.1: CVE--2026--33186 Improper Authorization

Affected range<1.79.3
Fixed version1.79.3
CVSS Score9.1
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
EPSS Score0.014%
EPSS Percentile3rd percentile
Description

Impact

What kind of vulnerability is it? Who is impacted?

It is an Authorization Bypass resulting from Improper Input Validation of the HTTP/2 :path pseudo-header.

The gRPC-Go server was too lenient in its routing logic, accepting requests where the :path omitted the mandatory leading slash (e.g., Service/Method instead of /Service/Method). While the server successfully routed these requests to the correct handler, authorization interceptors (including the official grpc/authz package) evaluated the raw, non-canonical path string. Consequently, "deny" rules defined using canonical paths (starting with /) failed to match the incoming request, allowing it to bypass the policy if a fallback "allow" rule was present.

Who is impacted?
This affects gRPC-Go servers that meet both of the following criteria:

  1. They use path-based authorization interceptors, such as the official RBAC implementation in google.golang.org/grpc/authz or custom interceptors relying on info.FullMethod or grpc.Method(ctx).
  2. Their security policy contains specific "deny" rules for canonical paths but allows other requests by default (a fallback "allow" rule).

The vulnerability is exploitable by an attacker who can send raw HTTP/2 frames with malformed :path headers directly to the gRPC server.

Patches

Has the problem been patched? What versions should users upgrade to?

Yes, the issue has been patched. The fix ensures that any request with a :path that does not start with a leading slash is immediately rejected with a codes.Unimplemented error, preventing it from reaching authorization interceptors or handlers with a non-canonical path string.

Users should upgrade to the following versions (or newer):

  • v1.79.3
  • The latest master branch.

It is recommended that all users employing path-based authorization (especially grpc/authz) upgrade as soon as the patch is available in a tagged release.

Workarounds

Is there a way for users to fix or remediate the vulnerability without upgrading?

While upgrading is the most secure and recommended path, users can mitigate the vulnerability using one of the following methods:

1. Use a Validating Interceptor (Recommended Mitigation)

Add an "outermost" interceptor to your server that validates the path before any other authorization logic runs:

func pathValidationInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
    if info.FullMethod == "" || info.FullMethod[0] != '/' {
        return nil, status.Errorf(codes.Unimplemented, "malformed method name")
    }   
    return handler(ctx, req)
}

// Ensure this is the FIRST interceptor in your chain
s := grpc.NewServer(
    grpc.ChainUnaryInterceptor(pathValidationInterceptor, authzInterceptor),
)

2. Infrastructure-Level Normalization

If your gRPC server is behind a reverse proxy or load balancer (such as Envoy, NGINX, or an L7 Cloud Load Balancer), ensure it is configured to enforce strict HTTP/2 compliance for pseudo-headers and reject or normalize requests where the :path header does not start with a leading slash.

3. Policy Hardening

Switch to a "default deny" posture in your authorization policies (explicitly listing all allowed paths and denying everything else) to reduce the risk of bypasses via malformed inputs.

critical: 1 high: 0 medium: 0 low: 0 google.golang.org/grpc 1.71.0 (golang)

pkg:golang/google.golang.org/grpc@1.71.0

critical 9.1: CVE--2026--33186 Improper Authorization

Affected range<1.79.3
Fixed version1.79.3
CVSS Score9.1
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
EPSS Score0.014%
EPSS Percentile3rd percentile
Description

Impact

What kind of vulnerability is it? Who is impacted?

It is an Authorization Bypass resulting from Improper Input Validation of the HTTP/2 :path pseudo-header.

The gRPC-Go server was too lenient in its routing logic, accepting requests where the :path omitted the mandatory leading slash (e.g., Service/Method instead of /Service/Method). While the server successfully routed these requests to the correct handler, authorization interceptors (including the official grpc/authz package) evaluated the raw, non-canonical path string. Consequently, "deny" rules defined using canonical paths (starting with /) failed to match the incoming request, allowing it to bypass the policy if a fallback "allow" rule was present.

Who is impacted?
This affects gRPC-Go servers that meet both of the following criteria:

  1. They use path-based authorization interceptors, such as the official RBAC implementation in google.golang.org/grpc/authz or custom interceptors relying on info.FullMethod or grpc.Method(ctx).
  2. Their security policy contains specific "deny" rules for canonical paths but allows other requests by default (a fallback "allow" rule).

The vulnerability is exploitable by an attacker who can send raw HTTP/2 frames with malformed :path headers directly to the gRPC server.

Patches

Has the problem been patched? What versions should users upgrade to?

Yes, the issue has been patched. The fix ensures that any request with a :path that does not start with a leading slash is immediately rejected with a codes.Unimplemented error, preventing it from reaching authorization interceptors or handlers with a non-canonical path string.

Users should upgrade to the following versions (or newer):

  • v1.79.3
  • The latest master branch.

It is recommended that all users employing path-based authorization (especially grpc/authz) upgrade as soon as the patch is available in a tagged release.

Workarounds

Is there a way for users to fix or remediate the vulnerability without upgrading?

While upgrading is the most secure and recommended path, users can mitigate the vulnerability using one of the following methods:

1. Use a Validating Interceptor (Recommended Mitigation)

Add an "outermost" interceptor to your server that validates the path before any other authorization logic runs:

func pathValidationInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
    if info.FullMethod == "" || info.FullMethod[0] != '/' {
        return nil, status.Errorf(codes.Unimplemented, "malformed method name")
    }   
    return handler(ctx, req)
}

// Ensure this is the FIRST interceptor in your chain
s := grpc.NewServer(
    grpc.ChainUnaryInterceptor(pathValidationInterceptor, authzInterceptor),
)

2. Infrastructure-Level Normalization

If your gRPC server is behind a reverse proxy or load balancer (such as Envoy, NGINX, or an L7 Cloud Load Balancer), ensure it is configured to enforce strict HTTP/2 compliance for pseudo-headers and reject or normalize requests where the :path header does not start with a leading slash.

3. Policy Hardening

Switch to a "default deny" posture in your authorization policies (explicitly listing all allowed paths and denying everything else) to reduce the risk of bypasses via malformed inputs.

critical: 0 high: 5 medium: 0 low: 0 openssl 3.3.3-r0 (apk)

pkg:apk/alpine/openssl@3.3.3-r0?os_name=alpine&os_version=3.21

high : CVE--2025--15467

Affected range<3.3.6-r0
Fixed version3.3.6-r0
EPSS Score0.819%
EPSS Percentile74th percentile
Description

high : CVE--2025--9230

Affected range<3.3.5-r0
Fixed version3.3.5-r0
EPSS Score0.034%
EPSS Percentile10th percentile
Description

high : CVE--2025--69421

Affected range<3.3.6-r0
Fixed version3.3.6-r0
EPSS Score0.034%
EPSS Percentile10th percentile
Description

high : CVE--2025--69420

Affected range<3.3.6-r0
Fixed version3.3.6-r0
EPSS Score0.290%
EPSS Percentile52nd percentile
Description

high : CVE--2025--69419

Affected range<3.3.6-r0
Fixed version3.3.6-r0
EPSS Score0.060%
EPSS Percentile19th percentile
Description
critical: 0 high: 3 medium: 0 low: 0 curl 8.12.1-r0 (apk)

pkg:apk/alpine/curl@8.12.1-r0?os_name=alpine&os_version=3.21

high : CVE--2026--3805

Affected range<=8.14.0-r0
Fixed versionNot Fixed
EPSS Score0.039%
EPSS Percentile12th percentile
Description

high : CVE--2025--9086

Affected range<8.14.1-r2
Fixed version8.14.1-r2
EPSS Score0.035%
EPSS Percentile10th percentile
Description

high : CVE--2025--5399

Affected range<8.14.1-r0
Fixed version8.14.1-r0
EPSS Score0.486%
EPSS Percentile65th percentile
Description
critical: 0 high: 2 medium: 0 low: 0 golang.org/x/crypto 0.32.0 (golang)

pkg:golang/golang.org/x/crypto@0.32.0

high : CVE--2025--47913

Affected range<0.43.0
Fixed version0.43.0
EPSS Score0.039%
EPSS Percentile12th percentile
Description

SSH clients receiving SSH_AGENT_SUCCESS when expecting a typed response will panic and cause early termination of the client process.

high : CVE--2025--22869

Affected range<0.35.0
Fixed version0.35.0
EPSS Score0.215%
EPSS Percentile44th percentile
Description

SSH servers which implement file transfer protocols are vulnerable to a denial of service attack from clients which complete the key exchange slowly, or not at all, causing pending content to be read into memory, but never transmitted.

critical: 0 high: 1 medium: 0 low: 0 github.com/go-jose/go-jose/v4 4.0.5 (golang)

pkg:golang/github.com/go-jose/go-jose@4.0.5#v4

high 7.5: CVE--2026--34986 Uncaught Exception

Affected range<4.1.4
Fixed version4.1.4
CVSS Score7.5
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Description

Impact

Decrypting a JSON Web Encryption (JWE) object will panic if the alg field indicates a key wrapping algorithm (one ending in KW, with the exception of A128GCMKW, A192GCMKW, and A256GCMKW) and the encrypted_key field is empty. The panic happens when cipher.KeyUnwrap() in key_wrap.go attempts to allocate a slice with a zero or negative length based on the length of the encrypted_key.

This code path is reachable from ParseEncrypted() / ParseEncryptedJSON() / ParseEncryptedCompact() followed by Decrypt() on the resulting object. Note that the parse functions take a list of accepted key algorithms. If the accepted key algorithms do not include any key wrapping algorithms, parsing will fail and the application will be unaffected.

This panic is also reachable by calling cipher.KeyUnwrap() directly with any ciphertext parameter less than 16 bytes long, but calling this function directly is less common.

Panics can lead to denial of service.

Fixed In

4.1.4 and v3.0.5

Workarounds

If the list of keyAlgorithms passed to ParseEncrypted() / ParseEncryptedJSON() / ParseEncryptedCompact() does not include key wrapping algorithms (those ending in KW), your application is unaffected.

If your application uses key wrapping, you can prevalidate to the JWE objects to ensure the encrypted_key field is nonempty. If your application accepts JWE Compact Serialization, apply that validation to the corresponding field of that serialization (the data between the first and second .).

Thanks

Go JOSE thanks Datadog's Security team for finding this issue.

critical: 0 high: 1 medium: 0 low: 0 golang.org/x/oauth2 0.26.0 (golang)

pkg:golang/golang.org/x/oauth2@0.26.0

high 7.5: CVE--2025--22868 Improper Validation of Syntactic Correctness of Input

Affected range<0.27.0
Fixed version0.27.0
CVSS Score7.5
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Score0.112%
EPSS Percentile30th percentile
Description

An attacker can pass a malicious malformed token which causes unexpected memory to be consumed during parsing.

critical: 0 high: 1 medium: 0 low: 0 go.opentelemetry.io/otel/sdk 1.35.0 (golang)

pkg:golang/go.opentelemetry.io/otel/sdk@1.35.0

high 7.0: CVE--2026--24051 Untrusted Search Path

Affected range>=1.21.0
<1.40.0
Fixed version1.40.0
CVSS Score7
CVSS VectorCVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
EPSS Score0.007%
EPSS Percentile1st percentile
Description

Impact

The OpenTelemetry Go SDK in version v1.20.0-1.39.0 is vulnerable to Path Hijacking (Untrusted Search Paths) on macOS/Darwin systems. The resource detection code in sdk/resource/host_id.go executes the ioreg system command using a search path. An attacker with the ability to locally modify the PATH environment variable can achieve Arbitrary Code Execution (ACE) within the context of the application.

Patches

This has been patched in d45961b, which was released with v1.40.0.

References

critical: 0 high: 1 medium: 0 low: 0 golang.org/x/crypto 0.36.0 (golang)

pkg:golang/golang.org/x/crypto@0.36.0

high : CVE--2025--47913

Affected range<0.43.0
Fixed version0.43.0
EPSS Score0.039%
EPSS Percentile12th percentile
Description

SSH clients receiving SSH_AGENT_SUCCESS when expecting a typed response will panic and cause early termination of the client process.

critical: 0 high: 1 medium: 0 low: 0 go.opentelemetry.io/otel/sdk 1.34.0 (golang)

pkg:golang/go.opentelemetry.io/otel/sdk@1.34.0

high 7.0: CVE--2026--24051 Untrusted Search Path

Affected range>=1.21.0
<1.40.0
Fixed version1.40.0
CVSS Score7
CVSS VectorCVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
EPSS Score0.007%
EPSS Percentile1st percentile
Description

Impact

The OpenTelemetry Go SDK in version v1.20.0-1.39.0 is vulnerable to Path Hijacking (Untrusted Search Paths) on macOS/Darwin systems. The resource detection code in sdk/resource/host_id.go executes the ioreg system command using a search path. An attacker with the ability to locally modify the PATH environment variable can achieve Arbitrary Code Execution (ACE) within the context of the application.

Patches

This has been patched in d45961b, which was released with v1.40.0.

References

critical: 0 high: 1 medium: 0 low: 0 github.com/golang-jwt/jwt/v4 4.5.1 (golang)

pkg:golang/github.com/golang-jwt/jwt@4.5.1#v4

high 8.7: CVE--2025--30204 Asymmetric Resource Consumption (Amplification)

Affected range<4.5.2
Fixed version4.5.2
CVSS Score8.7
CVSS VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
EPSS Score0.102%
EPSS Percentile28th percentile
Description

Summary

Function parse.ParseUnverified currently splits (via a call to strings.Split) its argument (which is untrusted data) on periods.

As a result, in the face of a malicious request whose Authorization header consists of Bearer followed by many period characters, a call to that function incurs allocations to the tune of O(n) bytes (where n stands for the length of the function's argument), with a constant factor of about 16. Relevant weakness: CWE-405: Asymmetric Resource Consumption (Amplification)

Details

See parse.ParseUnverified

Impact

Excessive memory allocation

critical: 0 high: 1 medium: 0 low: 0 c-ares 1.34.3-r0 (apk)

pkg:apk/alpine/c-ares@1.34.3-r0?os_name=alpine&os_version=3.21

high : CVE--2025--31498

Affected range<1.34.5-r0
Fixed version1.34.5-r0
EPSS Score0.618%
EPSS Percentile70th percentile
Description
critical: 0 high: 1 medium: 0 low: 0 github.com/golang-jwt/jwt 3.2.2+incompatible (golang)

pkg:golang/github.com/golang-jwt/jwt@3.2.2%2Bincompatible

high 8.7: CVE--2025--30204 Asymmetric Resource Consumption (Amplification)

Affected range>=3.2.0
<=3.2.2
Fixed versionNot Fixed
CVSS Score8.7
CVSS VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
EPSS Score0.102%
EPSS Percentile28th percentile
Description

Summary

Function parse.ParseUnverified currently splits (via a call to strings.Split) its argument (which is untrusted data) on periods.

As a result, in the face of a malicious request whose Authorization header consists of Bearer followed by many period characters, a call to that function incurs allocations to the tune of O(n) bytes (where n stands for the length of the function's argument), with a constant factor of about 16. Relevant weakness: CWE-405: Asymmetric Resource Consumption (Amplification)

Details

See parse.ParseUnverified

Impact

Excessive memory allocation

critical: 0 high: 1 medium: 0 low: 0 nghttp2 1.64.0-r0 (apk)

pkg:apk/alpine/nghttp2@1.64.0-r0?os_name=alpine&os_version=3.21

high : CVE--2026--27135

Affected range<=1.64.0-r0
Fixed versionNot Fixed
EPSS Score0.017%
EPSS Percentile4th percentile
Description
critical: 0 high: 1 medium: 0 low: 0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc 0.36.4 (golang)

pkg:golang/go.opentelemetry.io/contrib/instrumentation@0.36.4#google.golang.org/grpc/otelgrpc

high : CVE--2023--47108 OWASP Top Ten 2017 Category A9 - Using Components with Known Vulnerabilities

Affected range<0.46.0
Fixed version0.46.0
EPSS Score4.299%
EPSS Percentile89th percentile
Description

OpenTelemetry-Go Contrib is a collection of third-party packages for OpenTelemetry-Go. Prior to version 0.46.0, the grpc Unary Server Interceptor out of the box adds labels net.peer.sock.addr and net.peer.sock.port that have unbound cardinality. It leads to the server's potential memory exhaustion when many malicious requests are sent. An attacker can easily flood the peer address and port for requests. Version 0.46.0 contains a fix for this issue. As a workaround to stop being affected, a view removing the attributes can be used. The other possibility is to disable grpc metrics instrumentation by passing otelgrpc.WithMeterProvider option with noop.NewMeterProvider.

critical: 0 high: 1 medium: 0 low: 0 golang.org/x/oauth2 0.7.0 (golang)

pkg:golang/golang.org/x/oauth2@0.7.0

high 7.5: CVE--2025--22868 Improper Validation of Syntactic Correctness of Input

Affected range<0.27.0
Fixed version0.27.0
CVSS Score7.5
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Score0.112%
EPSS Percentile30th percentile
Description

An attacker can pass a malicious malformed token which causes unexpected memory to be consumed during parsing.

critical: 0 high: 1 medium: 0 low: 0 golang.org/x/crypto 0.35.0 (golang)

pkg:golang/golang.org/x/crypto@0.35.0

high : CVE--2025--47913

Affected range<0.43.0
Fixed version0.43.0
EPSS Score0.039%
EPSS Percentile12th percentile
Description

SSH clients receiving SSH_AGENT_SUCCESS when expecting a typed response will panic and cause early termination of the client process.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
.env.example (1)

31-37: Consider adding a brief comment explaining the two variable sets.

There are two similar-looking groups: POSTGRES_*_CPB (Lines 31-33) used by the PostgreSQL service for provisioning, and CPB_POSTGRES_* (Lines 34-37) used by n8n to connect. A short inline comment would help developers understand why both exist.

📝 Suggested clarification
 # CPB (Connecting People Bot) — Development
+# PostgreSQL provisioning variables (used by postgresql service in docker-compose)
 POSTGRES_DB_CPB=cpb_bot
 POSTGRES_USER_CPB=cpb_app
 POSTGRES_PASSWORD_CPB=cpb_password
+# CPB application connection variables (used by n8n service)
 CPB_POSTGRES_HOST=postgresql
 CPB_POSTGRES_DB=cpb_bot
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.env.example around lines 31 - 37, Add a short inline comment above the two
variable groups clarifying that POSTGRES_DB_CPB, POSTGRES_USER_CPB,
POSTGRES_PASSWORD_CPB are used by the PostgreSQL service for
provisioning/initialization, while CPB_POSTGRES_HOST, CPB_POSTGRES_DB,
CPB_POSTGRES_USER, CPB_POSTGRES_PASSWORD are the connection variables consumed
by n8n (or the app); place the comment immediately above the first group so
developers see the distinction when scanning the .env example.
scripts/init-db.sh (1)

8-8: Consider escaping N8N and Temporal passwords for consistency.

The CPB password is now properly escaped, but POSTGRES_PASSWORD_N8N (Line 8) and POSTGRES_PASSWORD_TEMPORAL (Line 12) are still injected raw into SQL. A single quote in these passwords would break initialization similarly.

For consistency and defense-in-depth, consider applying the same escaping pattern to all passwords in this script.

♻️ Proposed fix
 # Escape single quotes in CPB password for SQL safety
 ESCAPED_POSTGRES_PASSWORD_CPB="${POSTGRES_PASSWORD_CPB//\'/''}"
+ESCAPED_POSTGRES_PASSWORD_N8N="${POSTGRES_PASSWORD_N8N//\'/''}"
+ESCAPED_POSTGRES_PASSWORD_TEMPORAL="${POSTGRES_PASSWORD_TEMPORAL//\'/''}"

 psql -v ON_ERROR_STOP=1 --username "postgres" <<-EOSQL
-    CREATE USER "$POSTGRES_USER_N8N" WITH ENCRYPTED PASSWORD '$POSTGRES_PASSWORD_N8N';
+    CREATE USER "$POSTGRES_USER_N8N" WITH ENCRYPTED PASSWORD '$ESCAPED_POSTGRES_PASSWORD_N8N';
     CREATE DATABASE "$POSTGRES_DB_N8N" OWNER "$POSTGRES_USER_N8N";
     GRANT ALL PRIVILEGES ON DATABASE "$POSTGRES_DB_N8N" TO "$POSTGRES_USER_N8N";

-    CREATE USER "$POSTGRES_USER_TEMPORAL" WITH ENCRYPTED PASSWORD '$POSTGRES_PASSWORD_TEMPORAL';
+    CREATE USER "$POSTGRES_USER_TEMPORAL" WITH ENCRYPTED PASSWORD '$ESCAPED_POSTGRES_PASSWORD_TEMPORAL';

Also applies to: 12-12

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/init-db.sh` at line 8, The CREATE USER statements inject
POSTGRES_PASSWORD_N8N and POSTGRES_PASSWORD_TEMPORAL raw into SQL, which will
break if the passwords contain single quotes; update the script to mirror the
escaping used for CPB by replacing direct variable interpolation with the
escaped versions (use the same shell-escaping expression applied there) wherever
POSTGRES_PASSWORD_N8N and POSTGRES_PASSWORD_TEMPORAL are used (e.g., in the
CREATE USER and ALTER ROLE statements) so all three passwords are consistently
escaped before being embedded into the SQL commands.
scripts/cpb-setup-db.sh (1)

31-45: Identifier validation provides good SQL injection protection.

The validate_pg_identifier function correctly enforces PostgreSQL identifier rules (63-char limit, ^[a-zA-Z_][a-zA-Z0-9_]*$ pattern). This prevents crafted names from breaking or exploiting the SQL statements.

To satisfy the SonarCloud warning, consider adding an explicit return 0 at the function's end, though this is optional since the implicit return behavior is correct.

♻️ Optional fix for SonarCloud
     if [[ ! "$value" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]]; then
         echo "ERROR: ${name} contains invalid characters (must match ^[a-zA-Z_][a-zA-Z0-9_]*$)" >&2; exit 1
     fi
+    return 0
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/cpb-setup-db.sh` around lines 31 - 45, The SonarCloud warning
requests an explicit success return from the identifier validator: update the
validate_pg_identifier function to include an explicit "return 0" as the last
statement before the closing brace so the function always returns success when
validations pass; keep the current exit 1 behavior on failures and leave the
calls validate_pg_identifier "$CPB_USER" "POSTGRES_USER_CPB" and
validate_pg_identifier "$CPB_DB" "POSTGRES_DB_CPB" unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.env.example:
- Around line 31-37: Add a short inline comment above the two variable groups
clarifying that POSTGRES_DB_CPB, POSTGRES_USER_CPB, POSTGRES_PASSWORD_CPB are
used by the PostgreSQL service for provisioning/initialization, while
CPB_POSTGRES_HOST, CPB_POSTGRES_DB, CPB_POSTGRES_USER, CPB_POSTGRES_PASSWORD are
the connection variables consumed by n8n (or the app); place the comment
immediately above the first group so developers see the distinction when
scanning the .env example.

In `@scripts/cpb-setup-db.sh`:
- Around line 31-45: The SonarCloud warning requests an explicit success return
from the identifier validator: update the validate_pg_identifier function to
include an explicit "return 0" as the last statement before the closing brace so
the function always returns success when validations pass; keep the current exit
1 behavior on failures and leave the calls validate_pg_identifier "$CPB_USER"
"POSTGRES_USER_CPB" and validate_pg_identifier "$CPB_DB" "POSTGRES_DB_CPB"
unchanged.

In `@scripts/init-db.sh`:
- Line 8: The CREATE USER statements inject POSTGRES_PASSWORD_N8N and
POSTGRES_PASSWORD_TEMPORAL raw into SQL, which will break if the passwords
contain single quotes; update the script to mirror the escaping used for CPB by
replacing direct variable interpolation with the escaped versions (use the same
shell-escaping expression applied there) wherever POSTGRES_PASSWORD_N8N and
POSTGRES_PASSWORD_TEMPORAL are used (e.g., in the CREATE USER and ALTER ROLE
statements) so all three passwords are consistently escaped before being
embedded into the SQL commands.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 1f342094-f414-4d1b-ac02-ae64b504941d

📥 Commits

Reviewing files that changed from the base of the PR and between 8c673c3 and e74a8b7.

📒 Files selected for processing (4)
  • .env.example
  • docker-compose.prod.yml
  • scripts/cpb-setup-db.sh
  • scripts/init-db.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • docker-compose.prod.yml

@SashkoMarchuk
Copy link
Copy Markdown
Collaborator Author

Review Findings — Addressed in e74a8b7

Fixed (4 CodeRabbit findings)

# File Issue Fix
1 .env.example Duplicate CPB keys in production section override dev values Removed duplicate block, replaced with comment pointing to dev section
2 docker-compose.prod.yml Slack IDs defaulted to FILL_BEFORE_LAUNCH placeholders Changed to :? (required) — production now fails fast if missing
3 scripts/cpb-setup-db.sh Hardcoded -U postgres admin user Added CPB_POSTGRES_ADMIN_USER env var (defaults to postgres)
4 scripts/init-db.sh + cpb-setup-db.sh Unescaped CPB password in SQL (single-quote injection) Added proper bash escaping with ${VAR//\'/''}

CI Failures — Dismissed as False Positives

Check Reason
Docker Security Scanning (n8n) GitHub API rejects the Scout comment (body >65536 chars) — not related to this PR
SonarCloud Pre-existing issue, not introduced by this PR

Validation

  • docker compose config --quiet
  • bash -n on both shell scripts ✅
  • Multi-agent adversarial review (/ultra --xl) ✅ — 97% confidence

- Add clarifying comments in .env.example for provisioning vs connection vars
- Escape N8N and Temporal passwords in init-db.sh for consistency with CPB fix
- Add explicit return 0 to validate_pg_identifier (fixes SonarCloud S7682)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.env.example:
- Around line 118-122: Update the production-note paragraph in .env.example to
accurately reference the Development section range (change "lines 30-46" to
"lines 30-48") and include the runtime DB credential variable in the list: add
CPB_POSTGRES_PASSWORD (in addition to POSTGRES_PASSWORD_CPB/POSTGRES variants
already listed) so the production instructions explicitly tell users to set
CPB_POSTGRES_PASSWORD, CPB_POSTGRES_HOST, CPB_SLACK_BOT_TOKEN, CPB_CHANNEL_ID,
CPB_REPORT_CHANNEL_ID, CPB_ADMIN_SLACK_ID, and CPB_DEV_SLACK_ID when creating a
real .env from .env.example.

In `@scripts/init-db.sh`:
- Around line 9-24: Validate all seven identifier environment variables
(POSTGRES_USER_N8N, POSTGRES_DB_N8N, POSTGRES_USER_TEMPORAL,
POSTGRES_DB_TEMPORAL, POSTGRES_DB_TEMPORAL_VISIBILITY, POSTGRES_USER_CPB,
POSTGRES_DB_CPB) before invoking psql by reusing the identifier validation
function/logic from cpb-setup-db.sh (the implementation at lines 32–47) that
enforces the 63-character PostgreSQL limit, valid character set, and emits clear
errors; perform this validation in scripts/init-db.sh and abort with a
descriptive message if any identifier is invalid so that no unvalidated
identifier values are interpolated into the CREATE USER/CREATE DATABASE/GRANT
SQL block.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 09a8692d-889c-4698-b1fb-dd78e1229184

📥 Commits

Reviewing files that changed from the base of the PR and between e74a8b7 and 4c3dded.

📒 Files selected for processing (3)
  • .env.example
  • scripts/cpb-setup-db.sh
  • scripts/init-db.sh
✅ Files skipped from review due to trivial changes (1)
  • scripts/cpb-setup-db.sh

…note

- Add validate_pg_identifier to init-db.sh matching cpb-setup-db.sh pattern
- Validate all 7 database/user identifiers before SQL execution
- Fix .env.example production note: correct line range (30-48), add CPB_POSTGRES_PASSWORD

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@SashkoMarchuk
Copy link
Copy Markdown
Collaborator Author

Final Review Status — All Findings Resolved

Commits

  • e74a8b7 — Fix 4 Major CodeRabbit findings
  • 4c3dded — Fix 3 Nitpick findings + SonarCloud gate
  • 47d4221 — Add identifier validation to init-db.sh + fix production note

All 7 CodeRabbit Findings — Addressed

# Severity File Fix
1 Major .env.example Removed duplicate CPB production block
2 Major docker-compose.prod.yml Slack IDs now :? required
3 Major cpb-setup-db.sh Admin user configurable via CPB_POSTGRES_ADMIN_USER
4 Major init-db.sh + cpb-setup-db.sh Password escaping with ${VAR//\'/''}
5 Nitpick .env.example Added inline comments for provisioning vs connection vars
6 Nitpick init-db.sh N8N/Temporal passwords now escaped too
7 Nitpick cpb-setup-db.sh Added return 0 to validate_pg_identifier

Additional Improvement

  • Added validate_pg_identifier to init-db.sh matching cpb-setup-db.sh pattern — validates all 7 identifiers before SQL execution

CI Status

Check Status
lint, Dockerfile Linting, Service Availability, CodeQL, SonarCloud, CodeRabbit ✅ All pass
Docker Security Scanning (temporal) ❌ Docker Scout API 503 — external service error
Docker Security Scanning (n8n) ❌ GitHub comment body >65536 chars — API limit

Both Docker Security failures are infrastructure issues unrelated to this PR.

Switch 9 CPB environment variables from :?required to :-default in
docker-compose.prod.yml. Docker Compose evaluates all :?required vars
globally during file parsing — missing CPB vars would crash ALL services
(n8n, temporal, redis, oauth2-proxy), not just CPB functionality.

With :-default, deploys work safely without CPB vars configured. CPB
won't function (placeholder token, fake IDs) but nothing crashes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@SashkoMarchuk
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@SashkoMarchuk
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@automatization-bot automatization-bot self-requested a review April 4, 2026 05:32
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 5, 2026

@SashkoMarchuk SashkoMarchuk merged commit 09436df into main Apr 5, 2026
13 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants